
#include "cmd_db_worker.hpp"
#include "vty_manager.hpp"


cmd_db_worker::cmd_db_worker(int id, command_agent_if_ptr agent) 
: _id(id), _cmdagent(agent)
{
	PDBG("worker start (id: %d)!!!!\n", _id);
};

cmd_db_worker::~cmd_db_worker() {
	PDBG("close worker !!!!\n");
};

void cmd_db_worker::reg_write_func(WriteFunction func) 
{
	_send_ipc = func;
}

void cmd_db_worker::handle_ingress_msg(vty_ipc_message_t& msg) 
{
	__u32 vty_id, cmd, sub;
	string_vector opts;
	_ipcmsg.parse_msg(msg, vty_id, cmd, sub, opts);
	PDBG("RECV << ID(%d), CMD(%d), SUB(%d)\n",
			vty_id, cmd, sub);
	for (int idx=0; idx < opts.size(); idx++) {
		PDBG("\tOPT[%d]: %s\n", idx, opts[idx].c_str());
	}

	if (cmd == VTY_ADD_CMD) {
		sub = handle_rq_add_cmd(opts);
	} else if (cmd == VTY_ADD_MODE) {
		sub = handle_rq_add_mode(opts);
	} else if (cmd == VTY_ALARM) {
		vty_manager::instance()->receive_alram(opts[0]);
	} 
	else {
		sub = VTY_FAIL;
	}

	opts.clear();
	PDBG("RET ---> %d\n", sub);
	_ipcmsg.build_msg(vty_id, cmd, sub, opts, msg);
	send_ipc(msg);
}

bool cmd_db_worker::send_ipc(const ipc_message& msg)
{
	_send_ipc(msg);
	return true;
}

bool cmd_db_worker::send_ipc(const std::string msg) 
{
	return send_ipc(msg.c_str(), msg.length());
}

bool cmd_db_worker::send_ipc(const char* data, std::size_t size) {
	ipc_message     _msg;
	if (data == NULL) return false;
	if (_send_ipc == NULL) return false;
	_msg.body_length(size);
	memcpy(_msg.body(), data, _msg.body_length());
	_msg.encode_header();
	_send_ipc(_msg);
	return true;
}


__u32 cmd_db_worker::handle_rq_add_cmd(string_vector& opts)
{
	if (opts.size() != 7) {
		PDBG("opts num: %d\n", (int)opts.size());
		return VTY_FAIL;
	}

	io_service ioserv;  /* FIXME */
	tcp_resolver            resolver(ioserv);
	tcp_resolver::query     query(opts[0], opts[1]);
	tcp_endpoint            rep = *resolver.resolve(query);

	__u64 agent_id = strtoul(opts[5].c_str(), NULL, 16);
	__u64 function_id = strtoul(opts[6].c_str(), NULL, 16);
	if (_cmdagent->add_command(opts[2], opts[3], opts[4], rep, agent_id, function_id) != true)
		return VTY_FAIL;
	return VTY_SUCC;
}

__u32 cmd_db_worker::handle_rq_add_mode(string_vector& opts)
{
	if (opts.size() != 3) {
		PDBG("opts num: %d\n", (int)opts.size());
		return VTY_FAIL;
	}

	bool is_auth = (opts[2].compare("ture") == 0) ? true : false;
	if (_cmdagent->add_mode(opts[0], opts[1], is_auth) != true) {
		return VTY_FAIL;
	} 
	return VTY_SUCC;
}


